package cn.com.surker.lab.service.impl;

import cn.com.surker.common.MessageCenterException;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.lab.UploadTypeEnum;
import cn.com.surker.enums.production.indent.ProTypeEnum;
import cn.com.surker.lab.dao.LabExpendUploadDao;
import cn.com.surker.lab.dao.LabExpendUploadLineDao;
import cn.com.surker.lab.dao.LabLevelConstructDao;
import cn.com.surker.lab.entity.LabExpendUpload;
import cn.com.surker.lab.entity.LabExpendUploadLine;
import cn.com.surker.lab.entity.LabLevelConstruct;
import cn.com.surker.lab.service.LabExpendUploadService;
import cn.com.surker.lab.vo.LabExpendUploadLineVo;
import cn.com.surker.lab.vo.LabExpendUploadVo;
import cn.com.surker.production.dao.ProductionIndentDao;
import cn.com.surker.production.entity.ProductionIndent;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.SysOriginDao;
import cn.com.surker.system.entity.SysOrigin;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.OrderNoUtil;
import cn.com.surker.util.StringUtils;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
* <p>
    * 技术上传配合表 服务实现类
    * </p>
*
* @author admin
* @since 2024-10-25
*/
@Service
public class LabExpendUploadServiceImpl extends ServiceImpl<LabExpendUploadDao, LabExpendUpload> implements LabExpendUploadService {

    @Resource
    private LabExpendUploadLineDao labExpendUploadLineDao;
    @Resource
    private LabExpendUploadDao labExpendUploadDao;
    @Resource
    private ProductionIndentDao productionIndentDao;
    @Resource
    private LabLevelConstructDao levelConstructDao;
    @Resource
    private SysOriginDao originDao;

    @Override
	public List<LabExpendUpload> queryByIndentId(String dbCode, Long orgId, Long indentId, Long lineId) {
        if (orgId == null || indentId == null) {
            return null;
        }
		List<LabExpendUpload> labExpendUploads = labExpendUploadDao.queryByIndentId(dbCode, orgId, indentId, lineId);
		return labExpendUploads;
    }

    /**
     * 任务单配合比分页
     * @param searchVal
     * @param startTime 任务单创建时间
     * @param endTime
     * @param proType 任务单生产状态 0待供 1：正供 2 供毕 3 技术暂供 4 生产暂供
     * @param isUpload 是否上传 0未上传 1已上传
     * @param offset
     * @param limit
     * @return
     */
    public IPage findByIndentPage(String searchVal, String startTime, String endTime, Integer proType,
                                  Integer castType,Integer isUpload, Long strengthId, Integer offset, Integer limit) {
        QueryWrapper<ProductionIndent> query = initFullParam(searchVal, startTime, endTime, proType, castType, isUpload, strengthId);
        PageHelper.offsetPage(offset, limit);
        IPage<ProductionIndent> iPage = labExpendUploadDao.selectFullPage(new Page<>((offset + limit) /limit, limit), query);
        /**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

    /**
     * 上传配合比记录
     * @param indentId 任务单
     * @param lineIds
     * @param isUpload
     * @return
     */
    public List<Map<String, Object>> findUploadData(Long indentId, String lineIds, String lineCodes, String isUpload) {
        if (StringUtils.isAllParamNull(indentId, lineIds, isUpload, lineCodes))
            throw new MessageCenterException("获取上传配合比记录参数错误");
        String[] lineIds_ = lineIds.split(",");
        String[] isUpload_ = isUpload.split(",");
        String[] lineCodes_ = lineCodes.split(",");
        if (lineIds_ != null && lineIds_.length > 0) {
            List<Map<String, Object>> listMap = new ArrayList<>();
            QueryWrapper<LabExpendUpload> query = null;
            for (int i = 0; i < lineIds_.length; i++) {
                query = new QueryWrapper<>();
                query.eq("indent_id", indentId);
                query.eq("status", StateEnum.ENABLED.getCode());
                query.eq("upload_line", lineIds_[i]);
//                query.eq("is_upload", isUpload_[i]);//配比状态
                query.orderByDesc("create_time");
                List<LabExpendUpload> list = labExpendUploadDao.selectList(query);
                if (list == null || list.size() == 0)
                    continue;
                LabExpendUpload upload = list.get(0);//获取最新记录
                QueryWrapper<LabExpendUploadLine> qw = new QueryWrapper<>();
                qw.eq("status", StateEnum.ENABLED.getCode());
                qw.eq("lab_expend_upload_id", upload.getId());
                qw.orderByAsc("id");
                Map<String, Object> map = new HashMap<>();
                map.put("sumDosage", 0);
                map.put("minDosage", 0);
                map.put("maxDosage", 0);
                List<LabExpendUploadLine> uploadLines = labExpendUploadLineDao.selectList(qw);
                if (!StringUtils.isNull(upload.getLabLevelConstructId())) {
                    LabLevelConstruct levelConstruct = levelConstructDao.selectById(upload.getLabLevelConstructId());
                    if (levelConstruct != null) {
                        map.put("sumDosage", levelConstruct.getVolumeWeight());
                        map.put("minDosage", levelConstruct.getMinDosage());
                        map.put("maxDosage", levelConstruct.getMaxDosage());
                    }
                }

                map.put("lineId", upload.getUploadLine());
                map.put("lineCode", lineCodes_[i]);
                map.put("isUpload", isUpload_[i]);
                map.put("uploadId", upload.getId());
                map.put("lineData", uploadLines);
                map.put("time", DateUtil.convertString(upload.getCreateTime()));
                map.put("levelCode", upload.getLabLevelCode());
                map.put("constructId", upload.getLabLevelConstructId());

                listMap.add(map);
            }
            return listMap;
        }
        throw new MessageCenterException("解析上传配合比记录参数错误");
    }

    /**
     * 根据任务单查询上传记录
     * @param indentId
     * @return
     */
    public List<Map<String, Object>> findByIndent(String dbCode, Long indentId) {
        if (StringUtils.isNull(indentId))
            throw new MessageCenterException("参数错误");
        ProductionIndent indent = productionIndentDao.selectById(indentId);
        if (indent == null || indent.getStrengthId() == null)
            throw new MessageCenterException("任务单不存在或任务单没有强度等级");

        List<Map<String, Object>> list = labExpendUploadDao.findUploadHistory(dbCode, indentId, indent.getStrengthId());
        if (list == null || list.size() == 0)
            return null;
        return list;
    }

    /**
     * 保存上传信息
     * @param expendUpload
     * @return
     */
    public RestResultDto saveUpload(LabExpendUpload expendUpload) {
        if (expendUpload == null)
            throw new MessageCenterException("参数错误");
        ProductionIndent indent = productionIndentDao.selectById(expendUpload.getIndentId());
        if (indent == null || indent.getStatus().intValue() == 1 || indent.getType() == ProTypeEnum.END.getCode())
            throw new MessageCenterException("任务单不存在或已被禁用、供毕");
        expendUpload.setCreateTime(new Date());
        Integer code = labExpendUploadDao.insert(expendUpload);
        if (code > 0) {
            SysOrigin origin = originDao.selectById(expendUpload.getOrgId());
            String org = "暂无";
            if (origin != null)
                org = origin.getOriginName();
            String orderNo = OrderNoUtil.labUploadNo(expendUpload.getId(), expendUpload.getUploadLine(), org);//生产上传配合比单号
            expendUpload.setCode(orderNo);
            labExpendUploadDao.updateById(expendUpload);
            return RestResultDto.success("保存成功", expendUpload);
        }
        throw new MessageCenterException("保存失败");
    }

    /**
     * 修改上传信息
     * @param expendUpload
     * @return
     */
    public RestResultDto updateUpload(LabExpendUpload expendUpload) {
        if (expendUpload == null)
            throw new MessageCenterException("参数错误");
        ProductionIndent indent = productionIndentDao.selectById(expendUpload.getIndentId());
        if (indent == null || indent.getStatus().intValue() == 1 || indent.getType() == ProTypeEnum.END.getCode())
            throw new MessageCenterException("任务单不存在或已被禁用、供毕");
        LabExpendUpload expend = labExpendUploadDao.selectById(expendUpload.getId());
        if (expend == null || expend.getStatus() == 1)
            throw new MessageCenterException("业务数据不存在或已被禁用");
        expendUpload.setUpdateTime(new Date());
        Integer code = labExpendUploadDao.updateById(expendUpload);
        if (code > 0) {
            return RestResultDto.success("更新成功", expendUpload);
        }
        throw new MessageCenterException("更新失败");
    }

    /**
     * 修改上传信息状态
     * @param id
     * @param status
     * @param creator
     * @param remark
     * @return
     */
    public RestResultDto updateStatus(Long id, Integer status, String creator, String remark) {
        if (StringUtils.isAllParamNull(id, status))
            return RestResultDto.fail("参数错误");
        LabExpendUpload expend = labExpendUploadDao.selectById(id);
        if (expend == null || expend.getStatus() == 1)
            throw new MessageCenterException("业务数据不存在或已被禁用");
        if (!StringUtils.isNull(creator))
            expend.setUpdator(creator);
        if (!StringUtils.isNull(remark))
            expend.setRemark(remark);
        expend.setStatus(status);
        expend.setUpdateTime(new Date());
        Integer code = labExpendUploadDao.insert(expend);
        if (code > 0) {
            return RestResultDto.success("更新成功");
        }
        throw new MessageCenterException("更新失败");
    }

    protected QueryWrapper<ProductionIndent> initFullParam(String searchVal, String startTime, String endTime,
                                                           Integer proType, Integer castModelId, Integer isUpload,
                                                            Long strengthId) {
        QueryWrapper<ProductionIndent> qw = new QueryWrapper<>();
        if (StringUtils.isNotBlank(searchVal)) {
            qw.and(orderWrapper -> orderWrapper.like("b.name", searchVal).or()
                    .like("a.site", searchVal).or().like("a.code", searchVal)
                    .or().like("g.full_name", searchVal).or().like("a1.line_code", searchVal));
        }
        qw.isNull("a.erp_id");
        if (StringUtils.isNotBlank(startTime)) {
            qw.ge("a.dispatch_start_time", startTime);
        }
        if (StringUtils.isNotBlank(endTime)) {
            qw.lt("a.dispatch_start_time", endTime);
        }
        if (proType != null) {
            qw.eq("a.type", proType);
        }
        if (proType != null) {
            qw.eq("a.type", proType);
        }
        if (castModelId != null) {
            qw.eq("a.cast_mode_id", castModelId);
        }
        if (isUpload != null) {
            qw.eq("a1.is_upload", isUpload);
        }
        if (!StringUtils.isNull(strengthId)) {
            qw.inSql("a.strength_id", "select id from base_strength " +
                    " where level_id in (select level_id from base_strength\n" +
                    "   where id = " + strengthId + " and status = 0)");
        }
        qw.eq("a.status", StateEnum.ENABLED.getCode());
        qw.groupBy("a.id");
        qw.orderByAsc("a.type");
        qw.orderByDesc("a.id");
        return qw;
    }

    /**
     * 根据任务单ID查询上传记录
     * @param indentId
     * @return
     */
    public List<LabExpendUploadVo> findIndentHistory(String dbCode, Long indentId) {
        if (StringUtils.isNull(indentId))
            return null;
        List<LabExpendUploadVo> uploadVoList = labExpendUploadDao.findIndentHistory(dbCode, indentId);
        if (uploadVoList == null || uploadVoList.size() == 0)
            return null;
        return uploadVoList;
    }

	@Override
	public LabExpendUpload queryByCode(Long lineId, String code) {
		QueryWrapper qw = new QueryWrapper();
		qw.eq("status", StateEnum.ENABLED.getCode());
		qw.eq("upload_line", lineId);
		qw.eq("code", code);
		qw.last("limit 1");
		LabExpendUpload labExpendUpload = labExpendUploadDao.selectOne(qw);
		return labExpendUpload;
	}

    /**
     * 根据强度等级ID查询上传记录
     * @param strengthId
     * @return
     */
    public List<LabExpendUploadVo> findStrengthHistory(String dbCode, Long lineId, Long strengthId) {
        if (StringUtils.isAllParamNull(lineId, strengthId))
            return null;
        List<LabExpendUploadVo> uploadVoList = labExpendUploadDao.findStrengthHistory(dbCode, lineId, strengthId);
        if (uploadVoList == null || uploadVoList.size() == 0)
            return null;
        return uploadVoList;
    }

    /**
     * 查询生产线的保存配比记录
     * @return
     */
    public List<LabExpendUpload> findIndentOrLine(String dbCode,Long indentId, String lineIds) {
        if (StringUtils.isAllParamNull(dbCode, indentId, lineIds))
            throw new MessageCenterException("获取上传配合比记录参数错误");
        String[] lineIds_ = lineIds.split(",");
        if (lineIds_ == null || lineIds_.length == 0)
            throw new MessageCenterException("未获取到生产线信息");
        List<Long> lines = new ArrayList<>();
        for (int i = 0; i <lineIds_.length; i++) {
            lines.add(StringUtils.convertLong(lineIds_[i]));
        }
        List<LabExpendUpload> uploadList = labExpendUploadDao.findIndentOrLine(dbCode, indentId, lines);
        if (uploadList == null || uploadList.size() == 0)
            return null;
        return uploadList;
    }

    /**
     * 集中保存配合比
     * @param indentId
     * @param lineIds 需要上传生产线
     * @param uploadIndentIds 需要上传的任务单
     * @return
     */
    public List<LabExpendUpload> saveBatchUpload(String dbCode,Long indentId, String lineIds, Long orgId,
                                                 String uploadIndentIds, String orgName, String creator) {
        if (StringUtils.isAllParamNull(dbCode, indentId, lineIds, uploadIndentIds))
            throw new MessageCenterException("集中上传配比参数错误");
        uploadIndentIds += indentId;
        String[] lineIds_ = lineIds.split(",");
        if (lineIds_ == null || lineIds_.length == 0)
            throw new MessageCenterException("未获取到上传生产线信息");
        String[] uploadIndentIds_ = uploadIndentIds.split(",");
        if (uploadIndentIds_ == null || uploadIndentIds_.length == 0)
            throw new MessageCenterException("未获取到选中任务单信息");
        Date nowDate = new Date();
        List<LabExpendUpload> uploadList = new ArrayList<>();
        for (int i = 0; i < lineIds_.length; i++) {
            Long lineId = StringUtils.convertLong(lineIds_[i]);
            if (lineId < 1)
                throw new MessageCenterException("生产线标识不匹配");
            LabExpendUpload expendUpload = labExpendUploadDao.findLastLine(dbCode, indentId, lineId);
            if (expendUpload == null)
                throw new MessageCenterException("未获取到已保存任务单配比信息(生产线标识" + lineId +")");
            List<LabExpendUploadLineVo> uploadLineVoList =  labExpendUploadLineDao.findExpendUploadListV1(dbCode, expendUpload.getId());
            if (uploadLineVoList == null || uploadLineVoList.size() == 0)
                throw new MessageCenterException("未获取到已保存任务单配比子项信息(生产线标识" + lineId +")");

            for (int j = 0; j < uploadIndentIds_.length; j++) {
                Long uploadIndentId = StringUtils.convertLong(uploadIndentIds_[j]);
                if (uploadIndentId < 1)
                    throw new MessageCenterException("选中任务单标识不匹配");
                expendUpload.setId(null);
                expendUpload.setCreateTime(nowDate);
                expendUpload.setUpdateTime(nowDate);
                expendUpload.setCreator(creator);
                expendUpload.setIndentId(uploadIndentId);
                expendUpload.setIsUpload(UploadTypeEnum.DONE.getCode());
                expendUpload.setUpdator(creator);
                labExpendUploadDao.insert(expendUpload);
                String orderNo = OrderNoUtil.labUploadNo(expendUpload.getId(), lineId, orgName);//生产上传配合比单号
                expendUpload.setCode(orderNo);
                labExpendUploadDao.updateById(expendUpload);
                List<LabExpendUploadLine> list = new ArrayList<>();
                for (LabExpendUploadLineVo uploadLineVo : uploadLineVoList) {
                    LabExpendUploadLine uploadLine = BeanUtil.copyProperties(uploadLineVo, LabExpendUploadLineVo.class);
                    uploadLine.setId(null);
                    uploadLine.setCreator(creator);
                    uploadLine.setUpdator(creator);
                    uploadLine.setUpdateTime(nowDate);
                    uploadLine.setCreateTime(nowDate);
                    uploadLine.setLabExpendUploadId(expendUpload.getId());
                    list.add(uploadLine);
                }
                if (list == null || list.size() == 0)
                    throw new MessageCenterException("");

                Integer code = labExpendUploadLineDao.saveBatch(list);
                if (code < 1)
                    throw new MessageCenterException("保存配比子项材料信息异常");
                uploadList.add(expendUpload);
            }
        }
        if (uploadList == null || uploadList.size() == 0)
            throw new MessageCenterException("批量保存配合比信息异常");
        return uploadList;
    }
}